/*
helferlein.com ( http://www.helferlein.com )
Michael Tobisch

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions 
of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
DEALINGS IN THE SOFTWARE.
*/
using System.Collections;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Users;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.UI.Modules;
using System.Collections.Generic;
using DotNetNuke.Services.FileSystem;
using DotNetNuke.Common.Utilities;
using System.Text;
using System;
using DotNetNuke.Services.Exceptions;
using System.IO;
using DotNetNuke.Security.Permissions;

namespace helferlein.DNN.Modules.Form
{
   public class Base
   {
      public const string DEFAULT_FORM_HEADER_TEMPLATE = "<table width=\"100%\" cellpadding=\"2\" cellspacing=\"2\" border=\"0\"><colgroup><col width=\"30%\"><col width=\"69%\"><col width=\"1%\"></colgroup>";
      public const string DEFAULT_FORM_ITEM_TEMPLATE = "<tr valign=\"top\"><td style=\"white-space: nowrap;\">[PENCIL][LABEL]</td><td>[FORMITEM][VALIDATOR]</td><td>[REQUIREDIMAGE]</td></tr>";
      public const string DEFAULT_FORM_LABEL_TEMPLATE = "<tr><td colspan=\"3\">[PENCIL][FORMITEM]</td></tr>";
      public const string DEFAULT_FORM_FOOTER_TEMPLATE = "</table>";
      public const string UPLOAD_FOLDER = "ReceivedFiles";
      public const string THEMES_FOLDER = "Themes";
   }

   public enum FormItemType
   {
      TextBox = 1,
      TextArea = 2,
      DropDownList = 3,
      MultipleSelect = 4,
      Checkbox = 5,
      Label = 6,
      RadioButtonList = 7,
      EMailAddress = 8,
      WebSite = 9,
      Date = 10,
      SendTo = 11,
      FileUpload = 12,
      SendCopy = 13,
      Hidden = 14
   }

   public enum ShowAdditionalItems
   {
      NotAtAll = 1,
      AboveTheForm = 2,
      BelowTheForm = 3
   }

   public enum RequiredFieldMarkerType
   {
      StandardIcon = 1,
      Asterisk = 2,
      OtherIcon = 3,
      OtherText = 4,
      None = 5
   }

   public enum LinkTarget
   {
      None = 1,
      Blank = 2,
      Self = 3,
      Parent = 4,
      Top = 5
   }

   public enum SubmitButtonsAppearance
   {
      Link = 1,
      Button = 2,
      CommandButton = 3
   }

   public enum RenderingMethod
   {
      Default = 1,
      GridView = 2,
      XSL = 3
   }

   public static class Helpers
   {
      /// <summary>
      /// Determine whether the value of a FormItemType is suitable for the
      /// Submissions DropDownList text value in the FormSubmissionsEdit control or not
      /// </summary>
      /// <param name="fit">A FormItemType value</param>
      /// <returns>Appendable or not</returns>
      public static bool IsItemTypeAppendableToDropDownList(FormItemType fit)
      {
         return ((fit == FormItemType.TextBox) || (fit == FormItemType.EMailAddress));
      }

      public static bool IsItemGroupable(FormItemType fit)
      {
         return ((fit == FormItemType.DropDownList) || (fit == FormItemType.RadioButtonList) || (fit == FormItemType.Checkbox));
      }

      public static bool IsItemRenderableAsHeadline(FormItemType fit)
      {
         return ((fit == FormItemType.TextBox) || (fit == FormItemType.DropDownList) || (fit == FormItemType.RadioButtonList));
      }

      public static bool IsItemEmailAddress(FormItemType fit)
      {
         return (fit == FormItemType.EMailAddress);
      }

      public static bool ValueRequired(FormItemType fit)
      {
         return ((fit == FormItemType.DropDownList) || (fit == FormItemType.MultipleSelect) || (fit == FormItemType.Label) || (fit == FormItemType.RadioButtonList) || (fit == FormItemType.SendTo) || (fit == FormItemType.Hidden));
      }

      public static void CheckFolder(int portalID, string folder, bool checkWritePermissions)
      {
         // Remove trailing or starting slashes
         if (folder.StartsWith("/"))
            folder = folder.Substring(1);
         if (folder.EndsWith("/"))
            folder = folder.Substring(0, folder.Length - 1);

         PortalSettings ps = new PortalSettings(portalID);
         string[] folders = folder.Split(new char[] { '/' });

         // Check if the directory exists in the filesystem - if not, create it.
         StringBuilder path = new StringBuilder(String.Empty);
         StringBuilder physicalPath = new StringBuilder(ps.HomeDirectoryMapPath);
         for (int i = 0; i < folders.Length; i++)
         {
            if (!(physicalPath.ToString().EndsWith("\\")))
               physicalPath.Append("\\");
            string parentDirectory = physicalPath.ToString();
            physicalPath.Append(folders[i]);

            path.Append((path.ToString().EndsWith("/")) || (path.Length == 0) ? String.Empty : "/");
            if (!(Directory.Exists(physicalPath.ToString())))
            {
               // FileSystemUtils.AddFolder(ps, parentDirectory, folders[i], Convert.ToInt32(FolderController.StorageLocationTypes.InsecureFileSystem));
               FolderManager.Instance.AddFolder(ps.PortalId, String.Format("{0}{1}", path, folders[i]));
            }
            path.Append(folders[i]);
         }

         if (checkWritePermissions)
         {
            /* CHECK IF ALL USERS HAVE WRITE PERMISSIONS FOR THAT FOLDER!!!! */
            // FolderInfo fi = FileSystemUtils.GetFolder(portalID, folder);
            IFolderInfo fi = FolderManager.Instance.GetFolder(portalID, path.ToString());

            PermissionController permissionController = new PermissionController();
            ArrayList arr = permissionController.GetPermissionByCodeAndKey("SYSTEM_FOLDER", "WRITE");
            PermissionInfo pi = (PermissionInfo)arr[0];

            bool permissionChanged = false;

            foreach (FolderPermissionInfo fpi in fi.FolderPermissions)
            {
               if ((fpi.RoleID == -1) && (fpi.PermissionID == pi.PermissionID))
               {
                  fpi.AllowAccess = true;
                  permissionChanged = true;
                  break;
               }
            }
            if (!(permissionChanged))
            {
               FolderPermissionInfo writePermissionForReceivedFiles;
               writePermissionForReceivedFiles = new FolderPermissionInfo();
               writePermissionForReceivedFiles.RoleID = -1;
               writePermissionForReceivedFiles.PermissionID = pi.PermissionID;
               writePermissionForReceivedFiles.AllowAccess = true;
               fi.FolderPermissions.Add(writePermissionForReceivedFiles);
            }
            try
            {
               FolderPermissionController.SaveFolderPermissions(fi);
            }
            catch (Exception ex)
            {
               Exceptions.LogException(ex);
            }
         }
         // FileSystemUtils.SynchronizeFolder(portalID, ps.HomeDirectoryMapPath, String.Empty, true, true, true, true);
         FolderManager.Instance.Synchronize(portalID, String.Empty, true, true);
      }
   }

   public abstract class BaseController
   {
      private Hashtable _settings = null;
      private ModuleInfo _configuration;
      private PortalInfo _portalInfo = null;
      private TabInfo _tabInfo = null;
      private TabController _tabController = null;

      protected TabController TabController
      {
         get
         {
            if (_tabController == null)
               _tabController = new TabController();
            return _tabController;
         }
      }

      private ModuleController _moduleController = null;
      protected ModuleController ModuleController
      {
         get
         {
            if (_moduleController == null)
               _moduleController = new ModuleController();
            return _moduleController;
         }
      }

      private PortalController _portalController = null;
      protected PortalController PortalController
      {
         get
         {
            if (_portalController == null)
               _portalController = new PortalController();
            return _portalController;
         }
      }

      public int TabModuleID { get; set; }
      public UserInfo UserInfo { get; set; }
      public int TabID { get; set; }
      public int ModuleID { get; set; }
      public int PortalID { get; set; }

      public Hashtable Settings
      {
         get
         {
            if (_settings == null)
            {
               // _settings = this.ModuleController.GetModuleSettings(this.ModuleID);
               _settings = this.ModuleController.GetModule(this.ModuleID, Null.NullInteger, true).ModuleSettings;
               // Add the TabModuleSettings to the Settings
               // Hashtable tabModuleSettings = this.ModuleController.GetTabModuleSettings(this.TabModuleID);
               ModuleInfo module = this.ModuleController.GetModule(this.ModuleID, this.TabModuleID, true);
               Hashtable tabModuleSettings;
               try
               {
                  tabModuleSettings = module.TabModuleSettings;
               }
               catch
               {
                  tabModuleSettings = new Hashtable();
               }
               foreach (string key in tabModuleSettings.Keys)
                  _settings[key] = tabModuleSettings[key];
            }
            return _settings;
         }
         set { _settings = value; }
      }

      public ModuleInfo Configuration
      {
         get
         {
            if (_configuration == null)
               // _configuration = this.ModuleController.GetModule(this.ModuleID);
               _configuration = this.ModuleController.GetModule(this.ModuleID, Null.NullInteger, true);
            return _configuration;
         }
         set
         {
            _configuration = value;
            this.ModuleID = value.ModuleID;
            this.TabModuleID = value.TabModuleID;
            this.TabID = value.TabID;
            this.PortalID = value.PortalID;
         }
      }

      public PortalSettings PortalSettings
      {
         get
         {
            // return PortalController.GetCurrentPortalSettings();
            return PortalController.Instance.GetCurrentPortalSettings();
         }
      }

      public PortalInfo PortalInfo
      {
         get
         {
            if (_portalInfo == null)
               _portalInfo = this.PortalController.GetPortal(this.PortalID);
            return _portalInfo;
         }
      }

      public TabInfo TabInfo
      {
         get
         {
            if (_tabInfo == null)
               _tabInfo = this.TabController.GetTab(this.TabID, this.PortalID, false);
            return _tabInfo;
         }
      }

      //public void Initialize(int moduleID, int tabID, UserInfo userInfo)
      //{
      //   this.ModuleID = moduleID;
      //   this.TabID = tabID;
      //   this.UserInfo = userInfo;
      //}

      public void Initialize(ModuleInstanceContext moduleContext)
      {
         this.Settings = moduleContext.Settings;
         this.Configuration = moduleContext.Configuration;
         this.UserInfo = moduleContext.PortalSettings.UserInfo;
         this.PortalID = moduleContext.PortalSettings.PortalId;
      }

      public void Initialize(int portalID, int moduleID)
      {
         this.PortalID = portalID;
         this.ModuleID = moduleID;
      }

      //public void Initialize(ModuleInfo moduleInfo)
      //{
      //   this.Configuration = moduleInfo;
      //}
   }
}
